﻿
// 2019/2/19: 首个记录
// 2019/3/29: 添加注释
// 2019/10/11: 修改pragma once和include
// 2020/1/13: 接口完备性
// 2020/5/15: 移除编译warning

#ifndef ENV_SAMPLE_V2_H
#define ENV_SAMPLE_V2_H

#include "spadas.h"

namespace env_sample_v2
{
	using namespace spadas;

	enum WeatherType
	{
		WT_Unknown = 0, // 未知
		WT_Sunny = 1, // 晴
		WT_Cloudy = 2, // 阴
		WT_Rainy = 3, // 雨
		WT_Snowy = 4, // 雪
		WT_Foggy = 5, // 雾
		WT_Sand = 6, // 沙尘
	};

	enum RoadType
	{
		RT_Unknown = 0, // 未知
		RT_Highway = 1, // 高速路，无红绿灯，80~120KPH
		RT_CityExpress = 2, // 城市快速路，无红绿灯，60~80KPH
		RT_CityMain = 3, // 城市主干道，有红绿灯，推荐60KPH
		RT_GeneralRoad = 4, // 一般道路，有红绿灯，推荐40KPH
		RT_CountryRoad = 5, // 乡村道路，无红绿灯，~40KPH
	};

	enum SpotType
	{
		ST_Unknown = 0, // 未知
		ST_TollGate = 1, //收费站
		ST_ServiceArea = 2, //服务区
		ST_Tunnel = 3, //隧道
		ST_Accident = 4, //事故
		ST_Crossing = 5, // 路口
		ST_Roundabout = 7, // 环岛
		ST_HighwayEntrance = 8, // 高速入口
		ST_HighwayExit = 9, // 高速出口
		ST_Bridge = 10, // 桥
		ST_ExpressEntrance = 11, // 快速路入口
		ST_ExpressExit = 12, // 快速路出口
	};
	struct Spot
	{
		SpotType spotType; // 场所类型
		Double distance; // 到场所的距离 m
	};

	enum TrafficStatus
	{
		TF_Unknown = 0, // 未知
		TF_Open = 1, //畅通
		TF_Slow = 2, //缓慢
		TF_Crowded = 3, //拥挤
	};

	struct EnvSample
	{
		GlobalTimestamp timeStamp; // 时间戳

		WeatherType weatherType; // 天气类型
		OptionalDouble temperature; // 温度 °C
		OptionalDouble pm25; // ug/m3
		String roadName; // 道路名称
		OptionalInt speedLimit; // 道路限速 KPH
		RoadType roadType; // 道路类型
		OptionalDouble illumination; // 光照强度 lux
		OptionalDouble windSpeed; // 风速 m/s
		Array<Spot> spots; // 场所列表
		TrafficStatus trafficStatus; // 交通状况

		EnvSample()
		{
			weatherType = WT_Unknown;
			roadType = RT_Unknown;
			trafficStatus = TF_Unknown;
		}

		static String getProtocolName()
		{
			return "env-sample-v2";
		}

		static String getTitle()
		{
			return "Road name size,Spot count,Weather,Temperature[°C],PM2.5[ug/m3],Speed limit[KPH],Road type,Illumination[lux],Wind speed[m/s],Traffic status,Spots and road name bytes...";
		}

		static Bool supportInterpolation()
		{
			return FALSE;
		}

		GeneralSample toGeneralSample()
		{
			Binary roadNameBin = roadName.toBinary();

			GeneralSample sample;
			sample.timeStamp = timeStamp;
			sample.values = Array<OptionalDouble>(10 + spots.size() * 2 + roadNameBin.size());

			sample.values[0] = roadNameBin.size();
			sample.values[1] = spots.size();

			sample.values[2] = (UInt)weatherType;
			sample.values[3] = temperature;
			sample.values[4] = pm25;
			sample.values[5] = speedLimit.valid ? speedLimit.value : OptionalDouble();
			sample.values[6] = (UInt)roadType;
			sample.values[7] = illumination;
			sample.values[8] = windSpeed;
			sample.values[9] = (UInt)trafficStatus;

			for (UInt i = 0; i < spots.size(); i++)
			{
				sample.values[10 + 2 * i] = (UInt)spots[i].spotType;
				sample.values[10 + 2 * i + 1] = spots[i].distance;
			}

			for (UInt i = 0; i < roadNameBin.size(); i++)
			{
				sample.values[10 + spots.size() * 2 + i] = roadNameBin[i];
			}

			sample.significantCount = sample.values.size();
			return sample;
		}

		Bool fromGeneralSample(GeneralSample sample)
		{
			// 未实现
			return FALSE;
		}

		Bool fromGeneralSample(String protocol, GeneralSample sample)
		{
			// 未实现
			return FALSE;
		}

		static EnvSample interpolate(EnvSample& s1, Double w1, EnvSample& s2, Double w2, GlobalTimestamp time)
		{
			return EnvSample();
		}
	};
}

#endif
